package ar.com.larreta.comunes;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;

import org.apache.commons.beanutils.PropertyUtils;

import ar.com.larreta.excepciones.Excepcion;

public class DescriptorDePropiedad extends Objeto{

	private Object origen;
	protected PropertyDescriptor descriptor;
	
	protected Transformador transformador;

	public DescriptorDePropiedad(Object origen, PropertyDescriptor descriptor, Transformador transformador) {
		this.transformador = transformador;
		if ((origen != null) && (descriptor != null)) {
			this.origen = origen;
			this.descriptor = descriptor;
		} else {
			// FIXME: Lanzar excepcion
		}
	}

	public Boolean esCollection() {
		return Herramientas.esDelTipo(descriptor.getPropertyType(),
				Collection.class);
	}
	
	public Class getType(){
		return descriptor.getPropertyType();
	}

	public Boolean esCollectionClaseRelacionada() {
		Class relacionada = Transformador.getClaseRelacionada(descriptor.getPropertyType());
		return (relacionada != null)
				&& (Herramientas.esDelTipo(relacionada, Collection.class));
	}

	public Boolean sePuedeLeer() {
		return PropertyUtils.isReadable(origen, descriptor.getName());
	}

	public Boolean sePuedeEscribir() {
		return PropertyUtils.isWriteable(origen, descriptor.getName());
	}

	public String getNombre() {
		return descriptor.getName();
	}

	public Object getValor() throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		return PropertyUtils.getProperty(origen, descriptor.getName());
	}

	public void setValor(Object valor) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		PropertyUtils.setProperty(origen, descriptor.getName(), valor);
	}

	public Boolean esIgualAClaseRelacionada() {
		try {
			Class clase = PropertyUtils.getPropertyType(origen,
					descriptor.getName());
			Class relacionada = Transformador.getClaseRelacionada(clase);
			return (clase.equals(relacionada));
		} catch (IllegalAccessException e) {
			logger.error(Excepcion.getStackTrace(e));
		} catch (InvocationTargetException e) {
			logger.error(Excepcion.getStackTrace(e));
		} catch (NoSuchMethodException e) {
			logger.error(Excepcion.getStackTrace(e));
		}
		return Boolean.FALSE;
	}

	public void copiar(DescriptorDePropiedad origen)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException, InstantiationException {
		Object valor = null;
		valor = origen.getValor();
		if (!origen.esIgualAClaseRelacionada()) {
			valor = transformador.getObjetoNuevo(valor);
		}
		setValor(valor);
	}

}
